﻿using System;
using System.Collections.Generic;

namespace Activity.I
{
	/// <summary>
	/// Демонстрационная программа: Диспетчер ПК.
	/// </summary>
	public class PCDemo
	{
		/// <summary>
		/// Последний выбранный компьютер.
		/// </summary>
		public static PC pc;
		/// <summary>
		/// Коллекция всех доступных компьютеров.
		/// </summary>
		public static List<PC> machines;
		/// <summary>
		/// Флаг запроса на выход из программы.
		/// </summary>
		public static bool exit;

		/// <summary>
		/// Начало программы
		/// </summary>
		public static void Main ()
		{
			// Создаем начальные значения
			machines = new List<PC>();
			machines.Add(new PC("HOME-PC", "Windows 8"));
			machines.Add(new PC("WorkStation", "Windows 8.1"));
			machines.Add(new PC("HOST", "Linux"));

			// Отображаем меню до тех пор пока не выйдем
			while (!exit) Display(Menu.Welcome);
		}

		/// <summary>
		/// Считать данные введенные пользователем.
		/// </summary>
		/// <param name="message">Приглашение для ввода данных.</param>
		/// <returns>Возвращает целое число которое ввел пользователь; в противном случае -1.</returns>
		public static int ReadMenu (string message)
		{
			Console.Write(message);
			int retVal;
			if (int.TryParse(Console.ReadLine(), out retVal))
				return retVal;
			return -1;
		}

		/// <summary>
		/// Считать данные введенные пользователем.
		/// </summary>
		/// <param name="message">Приглашение для ввода данных.</param>
		/// <returns>Возвращает текст введенный пользователем.</returns>
		public static string ReadLine (string message)
		{
			Console.Write(message);
			return Console.ReadLine();
		}

		/// <summary>
		/// Главное меню.
		/// </summary>
		public static void Welcome ()
		{
			// Вывод меню
			Console.WriteLine("Диспетчер ПК\n");
			Console.WriteLine("1. Добавить компьютер");
			// Можно выбрать компьютер только если они существуют
			if (machines.Count > 0) Console.WriteLine("2. Выбрать компьютер");
			Console.WriteLine("3. Инструкция");
			Console.WriteLine("0. Выход");

			// Переход к выбранному меню
			var key = ReadMenu("\nВыбор[0-3]: ");
			if (key == 1) Display(Menu.CreatePC);
			else if (machines.Count > 0 && key == 2) Display(Menu.SelectPC);
			else if (key == 3) Display(Menu.Instructions);
			else if (key == 0) Display(Menu.Exit);
			else Display(Menu.Welcome);
		}

		/// <summary>
		/// Меню создания компьютера.
		/// </summary>
		public static void CreatePC ()
		{
			Console.WriteLine("Создание Нового ПК");
			var pcName = ReadLine("Имя: ");
			var pcOS = ReadLine("ОС: ");
			machines.Add(new PC(pcName, pcOS));

			// Возвращаемся в главное меню
			Display(Menu.Welcome);
		}

		/// <summary>
		/// Меню выбора компьютера.
		/// </summary>
		public static void SelectPC ()
		{
			Console.WriteLine("Регистр ПК\n");
			// Отображаем все компьютеры
			for (int i = 0; i < PC.Machines.Length; i++)
			{
				var machine = machines[i];
				Console.WriteLine("{0}.\t ПК: {1}", i + 1, machine.Name);
				Console.WriteLine("\t ОС: {0}", machine.OS);
				Console.WriteLine();
			}
			Console.WriteLine("0. Назад");

			var index = -1;
			var isValidIndex = false;
			// Пытаемся выбрать компьютер
			while (!isValidIndex)
			{
				index = ReadMenu(string.Format("\nВыбор [{0}-{1}]: ", 0, machines.Count));
				// Выход из меню
				if (index == 0) break;

				// Проверяем индекс предварительно дезориентировав поскольку 0 - выход из меню
				isValidIndex = --index >= 0 && index < machines.Count;
				if (!isValidIndex) Console.WriteLine("Ошибка: Выбранная опция вне диапазона возможных значений!");
			}
			if (isValidIndex) // Выбираем компьютер и переходим в меню авторизации
			{
				pc = PC.Machines[index];
				Display(Menu.LogInPC);
			}
			else Display(Menu.Welcome);
		}

		/// <summary>
		/// Меню авторизации ПК.
		/// </summary>
		public static void LogInPC ()
		{
			// Доступные сведения о ПК
			Console.WriteLine("ПК: {0}", pc.Name);
			Console.WriteLine("ОС: {0}", pc.OS);

			var key = -1;
			if (pc.IsLocked)
			{
				// Вывод меню
				Console.WriteLine("\n\t**Заблокирован**\n");
				Console.WriteLine("\t1. Войти");
				Console.WriteLine("\t0. Назад");
				key = ReadMenu("\nВыбор [0-1]: ");
				if (key == 1) // Авторизация
				{
					// Просим ввести пароль
					pc.Unlock(ReadLine("\nВведите пароль: "));
					// Проверяем подошел ли пароль
					if (pc.IsLocked)
					{
						Console.WriteLine("Ошибка: Неверный пароль!");
						ReadLine("Нажмите клавишу ввода для продолжения...");
					}
				}
			}
			else
			{
				// Вывод меню
				Console.WriteLine("\n\tДобро пожаловать обратно пользователь: {0}!\n", pc.User);
				Console.WriteLine("\t1. Заблокировать");
				Console.WriteLine("\t2. Сменить имя пользователя");
				Console.WriteLine("\t3. Сменить пароль");
				Console.WriteLine("\t9. Сброс настроек к заводским установкам");
				Console.WriteLine("\t0. Назад");
				key = ReadMenu("\nВыбор [0-9]: ");

				// Блокируем ПК при выходи и при запросе блокировки
				if (key == 0 || key == 1) pc.Lock();
				else if (key == 2) // Смена имени пользователя
				{
					// Просим ввести новое имя
					pc.ChangeUser(ReadLine("\nВведите новое имя пользователя: "));
					Console.WriteLine("Имя пользователя изменено!");
					ReadLine("Нажмите клавишу ввода для продолжения...");
				}
				else if (key == 3) // Смена пароля
				{
					// Просим ввести новый пароль
					var pass = ReadLine("\nВведите новый пароль: ");
					var pass2 = ReadLine("Введите пароль еще раз: ");
					if (pass == pass2)
					{
						pc.ChangePassword(pass);
						Console.WriteLine("Пароль изменен!");
					}
					else
					{
						Console.WriteLine("Ошибка: пороли не совпадают!");
					}
					ReadLine("Нажмите клавишу ввода для продолжения...");
				}
				else if (key == 9) // Сброс настроек
				{
					// Подтверждение операции
					Console.WriteLine("Предупреждение: Вы уверены что хотите сбросить настройки ПК?");
					Console.WriteLine("1. Нет!");
					Console.WriteLine("2. Да!");
					key = ReadMenu("\nВыбор [1-2]: ");
					if (key == 2) // Сбрасываем настройки и блокируем компьютер
					{
						pc.Reset();
						Console.WriteLine("ПК был сброшен к заводским установкам.");
						ReadLine("Нажмите клавишу ввода для возврата в меню авторизации...");
					}
				}
			}
			// Выбираем следующее меню
			if (key == 0) Display(Menu.SelectPC);
			else Display(Menu.LogInPC);
		}

		/// <summary>
		/// Меню рекомендаций производителя.
		/// </summary>
		public static void Instructions ()
		{
			Console.WriteLine("Инструкция Производителя\n");
			Console.WriteLine("Настройки ПК по умолчанию:\n");
			Console.WriteLine("Операционная Система [ОС]: \t\t{0}", PC.DefaultOS);
			Console.WriteLine("Имя персонального компьютера [ПК]: \t{0}", PC.DefaultName);
			Console.WriteLine("Пользователь: \t\t\t\t{0}", PC.DefaultUser);
			Console.WriteLine("Пароль: \t\t\t\t{0}", PC.DefaultPassword);
			ReadLine("\nНажмите клавишу ввода для возврата в главное меню...");
		}

		/// <summary>
		/// Выход из программы
		/// </summary>
		public static void Exit ()
		{
			exit = true;
		}

		/// <summary>
		/// Отобразить выбранное меню.
		/// </summary>
		/// <param name="menu">Меню которое нужно отобразить.</param>
		public static void Display (Menu menu)
		{
			Console.Clear();
			switch (menu)
			{
				case Menu.Welcome:
					Welcome();
					break;

				case Menu.CreatePC:
					CreatePC();
					break;

				case Menu.SelectPC:
					SelectPC();
					break;

				case Menu.LogInPC:
					LogInPC();
					break;

				case Menu.Instructions:
					Instructions();
					break;

				case Menu.Exit:
					Exit();
					break;

				default:
					throw new ArgumentOutOfRangeException("menu");
			}
		}

		/// <summary>
		/// Перечисление доступных меню в пределах текущей программы.
		/// </summary>
		public enum Menu
		{
			Welcome,
			CreatePC,
			SelectPC,
			LogInPC,
			Instructions,
			Exit
		}
	}
}
